package services

import (
	"TaskAssignmentSystem/internal/admin/dao"
	"TaskAssignmentSystem/pkg/db/mysql"
	"TaskAssignmentSystem/pkg/utils"
	"errors"
	"fmt"
	"gorm.io/gorm"
)

type SystemProductService struct {
}

const (
	ProductOnline  = 1
	ProductOffline = 0

	ProductTypeCash    = 1
	ProductTypeProduct = 2
)

func (s *SystemProductService) ProductFindAll(page, pageSize int64, param map[string]string) (int64, []dao.SystemProduct, error) {
	var serve CommonService[dao.SystemProduct]
	serve.Page = page
	serve.PageSize = pageSize
	serve.WhereStr = []string{}
	if utils.StringIsNotEmpty(param["product_id"]) {
		sql := "product_id like '%" + param["product_id"] + "%'"
		serve.WhereStr = append(serve.WhereStr, sql)
	}
	if utils.StringIsNotEmpty(param["product_name"]) {
		sql := "product_name like '%" + param["product_name"] + "%'"
		serve.WhereStr = append(serve.WhereStr, sql)
	}
	if utils.StringIsNotEmpty(param["product_type"]) {
		serve.WhereStr = append(serve.WhereStr, fmt.Sprintf("product_type = %s", param["product_type"]))
	}
	if utils.StringIsNotEmpty(param["status"]) {
		serve.WhereStr = append(serve.WhereStr, fmt.Sprintf("status = %s", param["status"]))
	}
	if utils.StringIsNotEmpty(param["product_price_min"]) {
		serve.WhereStr = append(serve.WhereStr, fmt.Sprintf("product_price >= %s", param["product_price_min"]))
	}
	if utils.StringIsNotEmpty(param["product_price_max"]) {
		serve.WhereStr = append(serve.WhereStr, fmt.Sprintf("product_price <= %s", param["product_price_max"]))
	}
	serve.Order = "sort"

	if advList, err := serve.SelectList(); err != nil {
		return 0, nil, err
	} else {
		return advList.Total, advList.Data, nil
	}
}

func (s *SystemProductService) ProductFindByProductId(productId string) (result *dao.SystemProduct, err error) {
	var common dao.Common[dao.SystemProduct]
	if data, err := common.First(map[string]interface{}{"product_id": productId}); err != nil {
		return nil, err
	} else {
		return &data, nil
	}
}

func (s *SystemProductService) ProductFindCashProduct() (result *dao.SystemProduct, err error) {
	var common dao.Common[dao.SystemProduct]
	if data, err := common.First(map[string]interface{}{"product_type": ProductTypeCash, "status": ProductOnline}); err != nil {
		return nil, err
	} else {
		return &data, nil
	}
}

func (s *SystemProductService) ProductUpdatePicturePath(productId, productPicturePath string) error {
	var common dao.Common[dao.SystemProduct]
	common.Query = map[string]interface{}{"product_id": productId}
	if err := common.Update(map[string]interface{}{"product_picture_path": productPicturePath}).Error; err != nil {
		return err
	}
	return nil
}

func (s *SystemProductService) ProductUpdateStatus(productId string, status uint) error {
	var common dao.Common[dao.SystemProduct]
	common.Query = map[string]interface{}{"product_id": productId}
	if err := common.Update(map[string]interface{}{"status": status}).Error; err != nil {
		return err
	}
	return nil
}

func (s *SystemProductService) ProductDel(productId string) error {
	var common dao.Common[dao.SystemProduct]
	if err := common.DeleteByStringColumn("product_id", productId).Error; err != nil {
		return err
	}
	return nil
}

func (s *SystemProductService) ProductBatchDel(productIds []string) error {
	var common dao.Common[dao.SystemProduct]
	if err := common.BatchDeleteByStringColumn("product_id", productIds).Error; err != nil {
		return err
	}
	return nil
}

func (u *SystemProductService) UpdateNumberSubtract(productId string, number int) error {
	//更新用户数据
	var commDao dao.Common[dao.SystemProduct]
	obj, err := commDao.First(map[string]interface{}{"product_id": productId})
	if err != nil {
		return errors.New("该商品不存在")
	}
	if obj.ProductNumber < number {
		return errors.New("该商品数量不足")
	}
	commDao.Query = map[string]interface{}{"product_id": productId}
	commDao.Update(map[string]interface{}{"product_number": gorm.Expr("product_number - ?", number)})
	return nil
}

func (s *SystemProductService) BatchImportProducts(products []*dao.SystemProduct) error {
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var ids []string
		for _, i := range products {
			ids = append(ids, i.ProductId)
		}
		var productDao dao.Common[dao.SystemProduct]
		productDao.Tx = tx
		err := productDao.BatchDeleteByStringColumn("product_id", ids).Error
		fmt.Println(err)
		if err := tx.Create(products).Error; err != nil {
			return err
		}
		return nil
	})
}

func (s *SystemProductService) BatchDelProducts(products []*dao.SystemProduct) error {
	_db := mysql.GetDB()
	return _db.Transaction(func(tx *gorm.DB) error {
		var ids []string
		for _, i := range products {
			ids = append(ids, i.ProductId)
		}
		var productDao dao.Common[dao.SystemProduct]
		productDao.Tx = tx
		if err := productDao.BatchDeleteByStringColumn("product_id", ids).Error; err != nil {
			return err
		} else {
			return nil
		}
	})
}
